/*!
 * \file FasterDefs.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 高性能数据结构定义文件
 * 
 * \details 本文件定义了WonderTrader框架中的高性能数据结构：
 *          - LongKey：32字节固定长度字符串键类型，适用于较长标识符
 *          - ShortKey：16字节固定长度字符串键类型，适用于较短标识符 
 *          - faster_hashmap/faster_hashset：基于Robin Hood哈希算法的高性能容器别名
 *          - 专门优化的哈希函数实现，提供更好的性能表现
 *          
 *          所有类型都进行了内存对齐优化，适合高频交易等对性能要求极高的场景。
 */
#pragma once
#include <string.h>
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/container_hash/hash.hpp>
#include "WTSMarcos.h"

#include "../FasterLibs/tsl/robin_map.h"
#include "../FasterLibs/tsl/robin_set.h"

NS_WTP_BEGIN

/*!
 * \brief 高性能哈希表类型别名
 * \details 基于Robin Hood哈希算法的tsl::robin_map，提供更好的性能和内存利用率
 */
#define faster_hashmap tsl::robin_map

/*!
 * \brief 高性能哈希集合类型别名
 * \details 基于Robin Hood哈希算法的tsl::robin_set，提供更好的性能和内存利用率
 */
#define faster_hashset tsl::robin_set

/*!
 * \brief 长键类型（32字节固定长度）
 * 
 * \details 专为高性能设计的固定长度字符串键类型，具有以下特点：
 *          - 固定32字节长度，内存对齐优化
 *          - 基于64位整数数组存储，提高比较效率
 *          - 支持字符串构造和查找操作
 *          - 提供高效的相等性比较
 *          - 适用于合约代码、策略标识等较长字符串键
 * 
 * \note 超过32字节的字符串会被截断，使用时需注意长度限制
 */
typedef struct _Longkey //char[32]
{
	/*!
	 * \brief 内部存储缓冲区
	 * \details 使用4个64位整数存储32字节数据，便于快速比较
	 */
	uint64_t	_buf[4] = { 0 };

	/*!
	 * \brief 默认构造函数
	 * \details 初始化所有字节为0
	 */
	_Longkey()
	{
	}

	/*!
	 * \brief 从C字符串构造
	 * \param s 源C字符串指针
	 * \details 复制字符串内容到内部缓冲区，超过32字节的部分会被截断
	 */
	_Longkey(const char* s)
	{
		auto len = strlen(s);
		memcpy(_buf , s, len);
	}

	/*!
	 * \brief 从std::string构造
	 * \param s 源std::string对象
	 * \details 复制字符串内容到内部缓冲区，超过32字节的部分会被截断
	 */
	_Longkey(const std::string& s)
	{
		memcpy(_buf, s.c_str(), s.size());
	}

	/*!
	 * \brief 拷贝构造函数
	 * \param rhs 源LongKey对象
	 * \details 直接复制32字节数据
	 */
	_Longkey(const _Longkey& rhs)
	{
		memcpy(_buf, rhs._buf, 32);
	}

	/*!
	 * \brief 相等性比较运算符
	 * \param b 比较对象
	 * \return true表示相等，false表示不等
	 * \details 通过比较4个64位整数实现高效比较
	 */
	bool operator ==(const _Longkey& b) const
	{
		return (_buf[0] == b._buf[0] && _buf[1] == b._buf[1] && _buf[2] == b._buf[2] && _buf[3] == b._buf[3]);
	}

	/*!
	 * \brief 获取C字符串表示
	 * \return 指向内部缓冲区的C字符串指针
	 * \details 直接返回内部缓冲区指针，调用者不应修改返回的内容
	 */
	const char* c_str() const { return (const char*)_buf; }

	/*!
	 * \brief 查找字符位置
	 * \param ch 要查找的字符
	 * \return 字符在字符串中的位置，未找到返回std::string::npos
	 * \details 在32字节范围内线性查找指定字符
	 */
	inline std::size_t find(char ch) const
	{
		const char* s = (const char*)_buf;
		for (std::size_t i = 0; i < 32; i++)
		{
			if (s[i] == ch)
				return i;
		}

		return std::string::npos;
	}

	/*!
	 * \brief 获取字符串长度
	 * \return 字符串的实际长度
	 * \details 使用strlen计算实际字符串长度，不包括结尾的null字符
	 */
	inline std::size_t size() const { return strlen((char*)_buf); }

} LongKey;

/*!
 * \brief 代码集合类型定义
 * \details 基于LongKey的高性能哈希集合，用于存储合约代码等标识符集合
 */
typedef faster_hashset<LongKey> CodeSet;

/*!
 * \brief 短键类型（16字节固定长度）
 * 
 * \details 专为高性能设计的固定长度字符串键类型，具有以下特点：
 *          - 固定16字节长度，内存对齐优化
 *          - 基于64位整数数组存储，提高比较效率  
 *          - 支持字符串构造和查找操作
 *          - 提供高效的相等性比较和排序比较
 *          - 适用于交易所代码、策略类型等较短字符串键
 * 
 * \note 超过16字节的字符串会被截断，使用时需注意长度限制
 */
typedef struct _ShortKey //char[16]
{
	/*!
	 * \brief 内部存储缓冲区
	 * \details 使用2个64位整数存储16字节数据，便于快速比较
	 */
	uint64_t	_buf[2] = { 0 };

	/*!
	 * \brief 默认构造函数
	 * \details 初始化所有字节为0
	 */
	_ShortKey()
	{
	}

	/*!
	 * \brief 从C字符串构造
	 * \param s 源C字符串指针
	 * \details 复制字符串内容到内部缓冲区，超过16字节的部分会被截断
	 */
	_ShortKey(const char* s)
	{
		auto len = strlen(s);
		memcpy(_buf, s, len);
	}

	/*!
	 * \brief 从std::string构造
	 * \param s 源std::string对象
	 * \details 复制字符串内容到内部缓冲区，超过16字节的部分会被截断
	 */
	_ShortKey(const std::string& s)
	{
		memcpy(_buf, s.c_str(), s.size());
	}

	/*!
	 * \brief 相等性比较运算符
	 * \param b 比较对象
	 * \return true表示相等，false表示不等
	 * \details 通过比较2个64位整数实现高效比较
	 */
	bool operator ==(const _ShortKey& b) const
	{
		return (_buf[0] == b._buf[0] && _buf[1] == b._buf[1]);
	}

	/*!
	 * \brief 小于比较运算符
	 * \param b 比较对象
	 * \return true表示当前对象小于b，false表示大于等于
	 * \details 使用memcmp进行字节级比较，支持排序操作
	 */
	bool operator <(const _ShortKey& b) const
	{
		return memcmp((void*)_buf, (void*)b._buf, 16);
	}

	/*!
	 * \brief 获取C字符串表示
	 * \return 指向内部缓冲区的C字符串指针
	 * \details 直接返回内部缓冲区指针，调用者不应修改返回的内容
	 */
	const char* c_str() const { return (const char*)_buf; }

	/*!
	 * \brief 查找字符位置
	 * \param ch 要查找的字符
	 * \return 字符在字符串中的位置，未找到返回std::string::npos
	 * \details 在16字节范围内线性查找指定字符
	 */
	inline std::size_t find(char ch) const
	{
		const char* s = (const char*)_buf;
		for (std::size_t i = 0; i < 16; i++)
		{
			if (s[i] == ch)
				return i;
		}

		return std::string::npos;
	}

	/*!
	 * \brief 获取字符串长度
	 * \return 字符串的实际长度
	 * \details 使用strlen计算实际字符串长度，不包括结尾的null字符
	 */
	inline std::size_t size() const { return strlen((char*)_buf); }
} ShortKey;

NS_WTP_END;

/*!
 * \brief std命名空间扩展
 * \details 为自定义键类型提供标准库哈希函数特化
 */
namespace std
{
	/*!
	 * \brief LongKey的哈希函数特化
	 * \details 为LongKey类型提供高效的哈希计算，支持在标准库容器中使用
	 */
	template<>
	struct hash<wtp::LongKey>
	{
		/*!
		 * \brief 哈希计算操作符
		 * \param key 要计算哈希的LongKey对象
		 * \return 计算得到的哈希值
		 * \details 使用组合哈希算法，对4个64位整数分别计算哈希并组合
		 */
		size_t operator()(const wtp::LongKey& key) const
		{
			size_t ret = 17;
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[0]);
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[1]);
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[2]);
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[3]);
			return ret;
		}
	};

	/*!
	 * \brief ShortKey的哈希函数特化
	 * \details 为ShortKey类型提供高效的哈希计算，支持在标准库容器中使用
	 */
	template<>
	struct hash<wtp::ShortKey>
	{
		/*!
		 * \brief 哈希计算操作符
		 * \param key 要计算哈希的ShortKey对象
		 * \return 计算得到的哈希值
		 * \details 使用组合哈希算法，对2个64位整数分别计算哈希并组合
		 */
		size_t operator()(const wtp::ShortKey& key) const
		{
			size_t ret = 17;
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[0]);
			ret = ret * 31 + boost::hash<uint64_t>()(key._buf[1]);
			return ret;
		}
	};
};